{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "## 使用 `czsc` 进行选股\n",
    "---\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.5.4\n"
     ]
    }
   ],
   "source": [
    "import sys\n",
    "sys.path.insert(0, \".\")\n",
    "sys.path.insert(0, \"..\")\n",
    "\n",
    "import czsc\n",
    "print(czsc.__version__)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "from datetime import datetime\n",
    "from typing import List\n",
    "import traceback\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "from tqdm import tqdm_notebook as tqdm\n",
    "from czsc.analyze import KlineAnalyze"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "# 导入聚宽数据\n",
    "from czsc.data.jq import *\n",
    "\n",
    "# 如果是第一次使用需要设置 token\n",
    "# set_token(\"手机号\", \"密码\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "### 缠论日线笔中枢三买选股\n",
    "---\n",
    "\n",
    "条件描述： 最近五笔走势，前三笔构成中枢，第四笔离开中枢，第五笔向下不回中枢\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "def selector(symbols: List):\n",
    "    \"\"\"输入股票列表，输入符合买点定义的股票\"\"\"\n",
    "    res = []\n",
    "    for symbol in tqdm(symbols, desc=\"缠论日线笔中枢三买选股\"):\n",
    "        try:\n",
    "            kline = get_kline(symbol=symbol, end_date=datetime.now(), freq=\"D\", count=1000)\n",
    "            ka = KlineAnalyze(kline, ma_params=(5, 34, 120, 233))\n",
    "            points = ka.bi_list[-6:]\n",
    "            \n",
    "            if len(points) == 6 and points[-1]['fx_mark'] == \"d\":\n",
    "                zs_g = min([x['bi'] for x in points[:4] if x['fx_mark'] == 'g'])\n",
    "                zs_d = max([x['bi'] for x in points[:4] if x['fx_mark'] == 'd'])\n",
    "                \n",
    "                if points[-1]['bi'] > zs_g > zs_d:\n",
    "                    res.append(symbol)\n",
    "                    \n",
    "        except:\n",
    "            traceback.print_exc()\n",
    "    return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "b33033a1bccb49338a8bedfb36f9ae1b",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "HBox(children=(IntProgress(value=0, description='缠论日线笔中枢三买选股', style=ProgressStyle(description_width='initial'…"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "选股结果： ['300133.XSHE']\n"
     ]
    }
   ],
   "source": [
    "# 在创业板中选股\n",
    "symbols = get_index_stocks(\"399006.XSHE\")\n",
    "selected = selector(symbols)\n",
    "\n",
    "print(\"选股结果：\", selected)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 日线笔中枢选股\n",
    "---\n",
    "\n",
    "中枢如果能当下确认，基本逻辑如下：\n",
    "1. ma 233<close<ma 60 ---得 codes_list1\n",
    "2. codes_list1中选择 符合日线笔中枢形态的，得codes_list2\n",
    "    * 2.1 笔中枢形态：方向下: 日线中枢完成，第四笔底分型\n",
    "3. codes_list2 中中枢第一笔到第四笔得日期跨度 date1\n",
    "4. date1时间跨度中，codes_list2 ma233 cross的个数，并标注 codes_list3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n"
     ]
    }
   ],
   "source": [
    "def cross_number(x1, x2):\n",
    "    \"\"\"输入两个序列，计算 x1 下穿 x2 的次数\"\"\"\n",
    "    x = np.array(x1) < np.array(x2)\n",
    "    num = 0\n",
    "    for i in range(len(x)-1):\n",
    "        b1, b2 = x[i], x[i+1]\n",
    "        if b2 and b1 != b2:\n",
    "            num += 1\n",
    "    return num\n",
    "\n",
    "x1 = [1, 1, 3, 4, 5, 12, 9, 8]\n",
    "x2 = [2, 2, 1, 5, 8, 9, 10, 3]\n",
    "print(cross_number(x1, x2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "def selector(symbols: List):\n",
    "    \"\"\"输入股票列表，输入符合买点定义的股票\"\"\"\n",
    "    res = []\n",
    "    for symbol in tqdm(symbols, desc=\"缠论选股\"):\n",
    "        try:\n",
    "            kline = get_kline(symbol=symbol, end_date=datetime.now(), freq=\"D\", count=1000)\n",
    "            ka = KlineAnalyze(kline, ma_params=(5, 34, 60, 250))\n",
    "\n",
    "            if ka.ma[-1]['ma60'] >= ka.latest_price >= ka.ma[-1]['ma250']:\n",
    "                # print(\"{} 满足条件1：ma60 > close > ma233\".format(symbol))\n",
    "                points = ka.bi_list[-7:]\n",
    "                \n",
    "                if len(points) == 7 and points[-1]['fx_mark'] == 'd':\n",
    "                    zs_g = min([x['bi'] for x in points[2:6] if x['fx_mark'] == 'g'])\n",
    "                    zs_d = max([x['bi'] for x in points[2:6] if x['fx_mark'] == 'd'])\n",
    "                    \n",
    "                    if zs_g > zs_d:\n",
    "                        # print(\"{} 满足条件2：向下中枢完成\".format(symbol))\n",
    "                        date_span = [points[-5]['dt'], points[-1]['dt']]\n",
    "                        low = [x['low'] for x in ka.kline_raw if date_span[1] >= x['dt'] >= date_span[0]]\n",
    "                        ma_ = [x['ma250'] for x in ka.ma if date_span[1] >= x['dt'] >= date_span[0]]\n",
    "                        num = cross_number(low, ma_)\n",
    "                        res.append({\"symbol\": symbol, \"cross_num\": num})\n",
    "        except:\n",
    "            traceback.print_exc()\n",
    "    return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "8da8cca5b5b34c53b4cd3bb4f25da4f6",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "HBox(children=(IntProgress(value=0, description='缠论选股', style=ProgressStyle(description_width='initial')), HTM…"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "选股结果： [{'symbol': '300003.XSHE', 'cross_num': 0}, {'symbol': '300223.XSHE', 'cross_num': 0}, {'symbol': '300383.XSHE', 'cross_num': 0}, {'symbol': '300567.XSHE', 'cross_num': 2}, {'symbol': '300633.XSHE', 'cross_num': 0}, {'symbol': '300661.XSHE', 'cross_num': 0}]\n"
     ]
    }
   ],
   "source": [
    "# 在创业板中选股\n",
    "symbols = get_index_stocks(\"399006.XSHE\")\n",
    "# symbols = get_index_stocks(\"000001.XSHG\")\n",
    "selected = selector(symbols)\n",
    "\n",
    "print(\"选股结果：\", selected)\n",
    "# df = pd.DataFrame(selected)\n",
    "# df.to_excel(\"选股结果.xlsx\", index=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
